package ecc;

import java.awt.Color;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JFrameECCLite.java
 *
 * Created on Jan 3, 2011, 4:00:40 PM
 */
/**
 *
 * @author mjunior
 */
public class JFrameECCLitePSEC extends javax.swing.JFrame {

	private SecureRandom rand;
	private BigInteger privateKey;
	private EPoint publicKey;
	private ECurve curve;
	private int numBits;
	private EPoint C1;

	/** Creates new form JFrameECCLite */
	public JFrameECCLitePSEC() {
		initComponents();

		//Centralizes the JFrame
		setLocationRelativeTo(null);

		byte[] randSeed = new byte[20];
		(new Random()).nextBytes(randSeed);
		/*
		for (int i = 0; i < randSeed.length; i++) {
		randSeed[i] = (byte)i;
		}
		//*/
		this.rand = new SecureRandom(randSeed);
	}

	private boolean genKeyPair(int bits) {
		System.out.print("Generating key pair for " + bits + "-bit...");

		this.numBits = bits;
		this.curve = ECurve.getStandardCurve(this.numBits); // load curve equation for E

		Object[] pair = ESigns.makeKeyPair(curve, rand);
		if (pair == null) {
			this.jLabelError.setText("unable to make key pair!");
			return false;
		}

		this.privateKey = (BigInteger) pair[0];
		this.publicKey = (EPoint) pair[1];

		return true;
	}

	private Object[] encrypt(String message) throws NoSuchAlgorithmException {

		EEncrypt ee = new EEncrypt();
		Object[] ciphertext = null;

		//*
		System.out.println("Testing " + this.numBits + "-bit PSEC encryption");
		long elapsed = -System.currentTimeMillis();
		int tests = 10;
		for (int i = 0; i < tests; i++) {
			ee.init(this.curve, MessageDigest.getInstance("SHA"), rand);
			//System.out.print("i");
			//sv.update(msg, 0, i); // sign the first i characters of msg
			ee.update(message.getBytes()); // signs the whole msg
			//System.out.print("u");
			ciphertext = ee.encrypt(publicKey);
			//System.out.print("s");
		}
		elapsed += System.currentTimeMillis();
		this.jLabelTimeSign.setText(elapsed + " ms");

		System.out.println(" done in " + 1.0 * elapsed / tests + " ms/sig.");

		return ciphertext;
	}

	private String decrypt(EPoint C1, byte[] c2, byte[] c3) throws NoSuchAlgorithmException {

		EEncrypt ee = new EEncrypt();
		byte[] plaintext = null;

		int tests = 10;
		long elapsed = -System.currentTimeMillis();
		for (int i = 0; i < tests; i++) {
			ee.init(this.curve, MessageDigest.getInstance("SHA"),
					privateKey, C1, c2);
			//System.out.print("i");
			//sv.update(msg, 0, i); // verify the first i characters of msg
			ee.update(c3); // verify the whole msg
			//System.out.print("u");

			plaintext = ee.decrypt();
		}
		elapsed += System.currentTimeMillis();
		this.jLabelTimeVerif.setText(elapsed + " ms");
		System.out.println(" done in " + 1.0 * elapsed / tests + " ms/sig.");

		if(plaintext == null){
			return null;
		}
		return new String(plaintext);
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanelContainer = new javax.swing.JPanel();
        jTextFieldMsg = new javax.swing.JTextField();
        jComboBoxCurveSize = new javax.swing.JComboBox();
        jTextFieldC1 = new javax.swing.JTextField();
        jButtonEncrypt = new javax.swing.JButton();
        jButtonDecrypt = new javax.swing.JButton();
        jLabelTimeSign = new javax.swing.JLabel();
        jLabelTimeVerif = new javax.swing.JLabel();
        jLabelResultValue = new javax.swing.JLabel();
        jLabelMsg = new javax.swing.JLabel();
        jLabelCiphertext = new javax.swing.JLabel();
        jLabelCurve = new javax.swing.JLabel();
        jLabelPublic = new javax.swing.JLabel();
        jLabelPrivate = new javax.swing.JLabel();
        jLabelPubValue = new javax.swing.JLabel();
        jLabelPrivValue = new javax.swing.JLabel();
        jButtonGenkey = new javax.swing.JButton();
        jSeparator = new javax.swing.JSeparator();
        jLabelError = new javax.swing.JLabel();
        jTextFieldC2 = new javax.swing.JTextField();
        jTextFieldC3 = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("ECCLite: PSEC-1+SHA1+OTP");
        setMinimumSize(new java.awt.Dimension(800, 300));
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanelContainer.setLayout(new java.awt.GridBagLayout());

        jTextFieldMsg.setText("Mensagem");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        jPanelContainer.add(jTextFieldMsg, gridBagConstraints);

        jComboBoxCurveSize.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "160", "192", "224", "256", "384", "521" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 4, 0);
        jPanelContainer.add(jComboBoxCurveSize, gridBagConstraints);

        jTextFieldC1.setEditable(false);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 9;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 0, 1, 0);
        jPanelContainer.add(jTextFieldC1, gridBagConstraints);

        jButtonEncrypt.setText("Encriptar");
        jButtonEncrypt.setActionCommand("Encriptar");
        jButtonEncrypt.setEnabled(false);
        jButtonEncrypt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonEncryptActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jButtonEncrypt, gridBagConstraints);

        jButtonDecrypt.setText("Decriptar");
        jButtonDecrypt.setEnabled(false);
        jButtonDecrypt.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonDecryptActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 13;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jButtonDecrypt, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
        jPanelContainer.add(jLabelTimeSign, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 13;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
        jPanelContainer.add(jLabelTimeVerif, gridBagConstraints);

        jLabelResultValue.setText(" ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 14;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        jPanelContainer.add(jLabelResultValue, gridBagConstraints);

        jLabelMsg.setLabelFor(jTextFieldMsg);
        jLabelMsg.setText("Mensagem:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
        jPanelContainer.add(jLabelMsg, gridBagConstraints);

        jLabelCiphertext.setLabelFor(jLabelCiphertext);
        jLabelCiphertext.setText("Cifrado: C1, c2, c3");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(20, 0, 2, 0);
        jPanelContainer.add(jLabelCiphertext, gridBagConstraints);

        jLabelCurve.setText("Curva: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelCurve, gridBagConstraints);

        jLabelPublic.setText("Pública: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPublic, gridBagConstraints);

        jLabelPrivate.setText("Privada: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPrivate, gridBagConstraints);

        jLabelPubValue.setText("-");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPubValue, gridBagConstraints);

        jLabelPrivValue.setText("-");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPrivValue, gridBagConstraints);

        jButtonGenkey.setText("Gerar Chaves");
        jButtonGenkey.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonGenkeyActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(11, 0, 5, 0);
        jPanelContainer.add(jButtonGenkey, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(9, 0, 9, 0);
        jPanelContainer.add(jSeparator, gridBagConstraints);

        jLabelError.setText(" ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 15;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(9, 0, 0, 0);
        jPanelContainer.add(jLabelError, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 11;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 5, 0);
        jPanelContainer.add(jTextFieldC2, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 10;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 1, 0);
        jPanelContainer.add(jTextFieldC3, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
        getContentPane().add(jPanelContainer, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonEncryptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonEncryptActionPerformed
		try {
			Object[] ciphertext = this.encrypt(this.jTextFieldMsg.getText());

			this.C1 = (EPoint) ciphertext[0];
			this.jTextFieldC1.setText(C1.toString());

			this.jTextFieldC2.setText(Util.getHexString((byte[]) ciphertext[1]));
			this.jTextFieldC3.setText(Util.getHexString((byte[]) ciphertext[2]));


			this.jButtonDecrypt.setEnabled(true);
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			ex.printStackTrace();
			this.jLabelError.setText(ex.toString());
			this.jButtonDecrypt.setEnabled(false);
		}


    }//GEN-LAST:event_jButtonEncryptActionPerformed

    private void jButtonGenkeyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonGenkeyActionPerformed

		boolean success = false;
		try {
			success = this.genKeyPair(Integer.parseInt(this.jComboBoxCurveSize.getSelectedItem().toString()));
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			this.jLabelError.setText(ex.toString());
		}

		if (success) {
			this.jLabelPrivValue.setText(this.privateKey.toString());
			this.jLabelPubValue.setText(this.publicKey.toString());
		} else {
			this.jLabelPrivValue.setText("-");
			this.jLabelPubValue.setText("-");
		}
		this.jButtonEncrypt.setEnabled(success);
		//this.jButtonVerify.setEnabled(false);


    }//GEN-LAST:event_jButtonGenkeyActionPerformed

	private void showResult(String str) {
		if (str != null) {
			this.jLabelResultValue.setText(str);
			this.jLabelResultValue.setForeground(Color.blue);
		} else {
			this.jLabelResultValue.setText("INVALIDA");
			this.jLabelResultValue.setForeground(Color.red);
		}
	}

    private void jButtonDecryptActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonDecryptActionPerformed

		String plain = null;
		try {
			plain = this.decrypt(this.C1,
					Util.hexStringToByteArray(this.jTextFieldC2.getText()),
					Util.hexStringToByteArray(this.jTextFieldC3.getText()));
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			ex.printStackTrace();
			this.jLabelError.setText(ex.toString());
		}

		this.showResult(plain);
    }//GEN-LAST:event_jButtonDecryptActionPerformed

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				new JFrameECCLitePSEC().setVisible(true);
			}
		});
	}
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButtonDecrypt;
    private javax.swing.JButton jButtonEncrypt;
    private javax.swing.JButton jButtonGenkey;
    private javax.swing.JComboBox jComboBoxCurveSize;
    private javax.swing.JLabel jLabelCiphertext;
    private javax.swing.JLabel jLabelCurve;
    private javax.swing.JLabel jLabelError;
    private javax.swing.JLabel jLabelMsg;
    private javax.swing.JLabel jLabelPrivValue;
    private javax.swing.JLabel jLabelPrivate;
    private javax.swing.JLabel jLabelPubValue;
    private javax.swing.JLabel jLabelPublic;
    private javax.swing.JLabel jLabelResultValue;
    private javax.swing.JLabel jLabelTimeSign;
    private javax.swing.JLabel jLabelTimeVerif;
    private javax.swing.JPanel jPanelContainer;
    private javax.swing.JSeparator jSeparator;
    private javax.swing.JTextField jTextFieldC1;
    private javax.swing.JTextField jTextFieldC2;
    private javax.swing.JTextField jTextFieldC3;
    private javax.swing.JTextField jTextFieldMsg;
    // End of variables declaration//GEN-END:variables
}
